Completed
Push — master ( 8967bc...e88c19 )
by Rain
02:47
created

Message.js ➔ ???   B

Complexity

Conditions 1

Size

Total Lines 81

Duplication

Lines 0
Ratio 0 %

Importance

Changes 44
Bugs 0 Features 0
Metric Value
cc 1
c 44
b 0
f 0
dl 0
loc 81
rs 8.8076

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
2
import _ from '_';
3
import $ from '$';
4
import ko from 'ko';
5
6
import {MessagePriority, SignedVerifyStatus} from 'Common/Enums';
7
8
import {
9
	pInt, inArray, isArray, isUnd, trim,
10
	previewMessage, windowResize, friendlySize, isNonEmptyArray
11
} from 'Common/Utils';
12
13
import {$win} from 'Common/Globals';
14
import {messageViewLink, messageDownloadLink} from 'Common/Links';
15
16
import {emailArrayFromJson, emailArrayToStringClear, emailArrayToString, replyHelper} from 'Helper/Message';
17
18
import {AttachmentModel, staticCombinedIconClass} from 'Model/Attachment';
19
import {AbstractModel} from 'Knoin/AbstractModel';
20
21
class MessageModel extends AbstractModel
22
{
23
	constructor() {
24
		super('MessageModel');
25
26
		this.folderFullNameRaw = '';
27
		this.uid = '';
28
		this.hash = '';
29
		this.requestHash = '';
30
		this.subject = ko.observable('');
31
		this.subjectPrefix = ko.observable('');
32
		this.subjectSuffix = ko.observable('');
33
		this.size = ko.observable(0);
34
		this.dateTimeStampInUTC = ko.observable(0);
35
		this.priority = ko.observable(MessagePriority.Normal);
36
37
		this.proxy = false;
38
39
		this.fromEmailString = ko.observable('');
40
		this.fromClearEmailString = ko.observable('');
41
		this.toEmailsString = ko.observable('');
42
		this.toClearEmailsString = ko.observable('');
43
44
		this.senderEmailsString = ko.observable('');
45
		this.senderClearEmailsString = ko.observable('');
46
47
		this.emails = [];
48
49
		this.from = [];
50
		this.to = [];
51
		this.cc = [];
52
		this.bcc = [];
53
		this.replyTo = [];
54
		this.deliveredTo = [];
55
		this.unsubsribeLinks = [];
56
57
		this.newForAnimation = ko.observable(false);
58
59
		this.deleted = ko.observable(false);
60
		this.deletedMark = ko.observable(false);
61
		this.unseen = ko.observable(false);
62
		this.flagged = ko.observable(false);
63
		this.answered = ko.observable(false);
64
		this.forwarded = ko.observable(false);
65
		this.isReadReceipt = ko.observable(false);
66
67
		this.focused = ko.observable(false);
68
		this.selected = ko.observable(false);
69
		this.checked = ko.observable(false);
70
		this.hasAttachments = ko.observable(false);
71
		this.attachmentsSpecData = ko.observableArray([]);
72
73
		this.attachmentIconClass = ko.computed(() => staticCombinedIconClass(this.hasAttachments() ? this.attachmentsSpecData() : []));
74
75
		this.body = null;
76
77
		this.isHtml = ko.observable(false);
78
		this.hasImages = ko.observable(false);
79
		this.attachments = ko.observableArray([]);
80
81
		this.isPgpSigned = ko.observable(false);
82
		this.isPgpEncrypted = ko.observable(false);
83
		this.pgpSignedVerifyStatus = ko.observable(SignedVerifyStatus.None);
84
		this.pgpSignedVerifyUser = ko.observable('');
85
86
		this.priority = ko.observable(MessagePriority.Normal);
87
		this.readReceipt = ko.observable('');
88
89
		this.aDraftInfo = [];
90
		this.sMessageId = '';
91
		this.sInReplyTo = '';
92
		this.sReferences = '';
93
94
		this.hasUnseenSubMessage = ko.observable(false);
95
		this.hasFlaggedSubMessage = ko.observable(false);
96
97
		this.threads = ko.observableArray([]);
98
99
		this.threadsLen = ko.computed(() => this.threads().length);
100
		this.isImportant = ko.computed(() => MessagePriority.High === this.priority());
101
102
		this.regDisposables([this.attachmentIconClass, this.threadsLen, this.isImportant]);
103
	}
104
105
	/**
106
	 * @static
107
	 * @param {AjaxJsonMessage} oJsonMessage
0 ignored issues
show
Documentation introduced by
The parameter oJsonMessage does not exist. Did you maybe forget to remove this comment?
Loading history...
108
	 * @returns {?MessageModel}
109
	 */
110
	static newInstanceFromJson(json) {
111
		const oMessageModel = new MessageModel();
112
		return oMessageModel.initByJson(json) ? oMessageModel : null;
113
	}
114
115
	clear() {
116
		this.folderFullNameRaw = '';
117
		this.uid = '';
118
		this.hash = '';
119
		this.requestHash = '';
120
		this.subject('');
121
		this.subjectPrefix('');
122
		this.subjectSuffix('');
123
		this.size(0);
124
		this.dateTimeStampInUTC(0);
125
		this.priority(MessagePriority.Normal);
126
127
		this.proxy = false;
128
129
		this.fromEmailString('');
130
		this.fromClearEmailString('');
131
		this.toEmailsString('');
132
		this.toClearEmailsString('');
133
		this.senderEmailsString('');
134
		this.senderClearEmailsString('');
135
136
		this.emails = [];
137
138
		this.from = [];
139
		this.to = [];
140
		this.cc = [];
141
		this.bcc = [];
142
		this.replyTo = [];
143
		this.deliveredTo = [];
144
		this.unsubsribeLinks = [];
145
146
		this.newForAnimation(false);
147
148
		this.deleted(false);
149
		this.deletedMark(false);
150
		this.unseen(false);
151
		this.flagged(false);
152
		this.answered(false);
153
		this.forwarded(false);
154
		this.isReadReceipt(false);
155
156
		this.selected(false);
157
		this.checked(false);
158
		this.hasAttachments(false);
159
		this.attachmentsSpecData([]);
160
161
		this.body = null;
162
		this.isHtml(false);
163
		this.hasImages(false);
164
		this.attachments([]);
165
166
		this.isPgpSigned(false);
167
		this.isPgpEncrypted(false);
168
		this.pgpSignedVerifyStatus(SignedVerifyStatus.None);
169
		this.pgpSignedVerifyUser('');
170
171
		this.priority(MessagePriority.Normal);
172
		this.readReceipt('');
173
		this.aDraftInfo = [];
174
		this.sMessageId = '';
175
		this.sInReplyTo = '';
176
		this.sReferences = '';
177
178
		this.threads([]);
179
180
		this.hasUnseenSubMessage(false);
181
		this.hasFlaggedSubMessage(false);
182
	}
183
184
	/**
185
	 * @param {Array} properties
186
	 * @returns {Array}
187
	 */
188
	getEmails(properties) {
189
		return _.compact(_.uniq(_.map(
190
			_.reduce(properties, (carry, property) => carry.concat(this[property]), []),
191
			(oItem) => (oItem ? oItem.email : '')
192
		)));
193
	}
194
195
	/**
196
	 * @returns {Array}
197
	 */
198
	getRecipientsEmails() {
199
		return this.getEmails(['to', 'cc']);
200
	}
201
202
	/**
203
	 * @returns {string}
204
	 */
205
	friendlySize() {
206
		return friendlySize(this.size());
207
	}
208
209
	computeSenderEmail() {
210
		const
211
			sentFolder = require('Stores/User/Folder').sentFolder(),
212
			draftFolder = require('Stores/User/Folder').draftFolder();
213
214
		this.senderEmailsString(this.folderFullNameRaw === sentFolder || this.folderFullNameRaw === draftFolder ?
215
			this.toEmailsString() : this.fromEmailString());
216
217
		this.senderClearEmailsString(this.folderFullNameRaw === sentFolder || this.folderFullNameRaw === draftFolder ?
218
			this.toClearEmailsString() : this.fromClearEmailString());
219
	}
220
221
	/**
222
	 * @param {AjaxJsonMessage} json
223
	 * @returns {boolean}
224
	 */
225
	initByJson(json) {
226
		let
227
			result = false,
228
			priority = MessagePriority.Normal;
0 ignored issues
show
Unused Code introduced by
The assignment to variable priority seems to be never used. Consider removing it.
Loading history...
229
230
		if (json && 'Object/Message' === json['@Object'])
231
		{
232
			priority = pInt(json.Priority);
233
			this.priority(-1 < inArray(priority, [MessagePriority.High, MessagePriority.Low]) ? priority : MessagePriority.Normal);
234
235
			this.folderFullNameRaw = json.Folder;
236
			this.uid = json.Uid;
237
			this.hash = json.Hash;
238
			this.requestHash = json.RequestHash;
239
240
			this.proxy = !!json.ExternalProxy;
241
242
			this.size(pInt(json.Size));
243
244
			this.from = emailArrayFromJson(json.From);
245
			this.to = emailArrayFromJson(json.To);
246
			this.cc = emailArrayFromJson(json.Cc);
247
			this.bcc = emailArrayFromJson(json.Bcc);
248
			this.replyTo = emailArrayFromJson(json.ReplyTo);
249
			this.deliveredTo = emailArrayFromJson(json.DeliveredTo);
250
			this.unsubsribeLinks = isNonEmptyArray(json.UnsubsribeLinks) ? json.UnsubsribeLinks : [];
251
252
			this.subject(json.Subject);
253
			if (isArray(json.SubjectParts))
254
			{
255
				this.subjectPrefix(json.SubjectParts[0]);
256
				this.subjectSuffix(json.SubjectParts[1]);
257
			}
258
			else
259
			{
260
				this.subjectPrefix('');
261
				this.subjectSuffix(this.subject());
262
			}
263
264
			this.dateTimeStampInUTC(pInt(json.DateTimeStampInUTC));
265
			this.hasAttachments(!!json.HasAttachments);
266
			this.attachmentsSpecData(isArray(json.AttachmentsSpecData) ? json.AttachmentsSpecData : []);
267
268
			this.fromEmailString(emailArrayToString(this.from, true));
269
			this.fromClearEmailString(emailArrayToStringClear(this.from));
270
			this.toEmailsString(emailArrayToString(this.to, true));
271
			this.toClearEmailsString(emailArrayToStringClear(this.to));
272
273
			this.threads(isArray(json.Threads) ? json.Threads : []);
274
275
			this.initFlagsByJson(json);
276
			this.computeSenderEmail();
277
278
			result = true;
279
		}
280
281
		return result;
282
	}
283
284
	/**
285
	 * @param {AjaxJsonMessage} json
286
	 * @returns {boolean}
287
	 */
288
	initUpdateByMessageJson(json) {
289
		let
290
			result = false,
291
			priority = MessagePriority.Normal;
0 ignored issues
show
Unused Code introduced by
The assignment to variable priority seems to be never used. Consider removing it.
Loading history...
292
293
		if (json && 'Object/Message' === json['@Object'])
294
		{
295
			priority = pInt(json.Priority);
296
			this.priority(-1 < inArray(priority, [MessagePriority.High, MessagePriority.Low]) ?
297
				priority : MessagePriority.Normal);
298
299
			this.aDraftInfo = json.DraftInfo;
300
301
			this.sMessageId = json.MessageId;
302
			this.sInReplyTo = json.InReplyTo;
303
			this.sReferences = json.References;
304
305
			this.proxy = !!json.ExternalProxy;
306
307
			if (require('Stores/User/Pgp').capaOpenPGP())
308
			{
309
				this.isPgpSigned(!!json.PgpSigned);
310
				this.isPgpEncrypted(!!json.PgpEncrypted);
311
			}
312
313
			this.hasAttachments(!!json.HasAttachments);
314
			this.attachmentsSpecData(isArray(json.AttachmentsSpecData) ? json.AttachmentsSpecData : []);
315
316
			this.foundedCIDs = isArray(json.FoundedCIDs) ? json.FoundedCIDs : [];
317
			this.attachments(this.initAttachmentsFromJson(json.Attachments));
318
319
			this.readReceipt(json.ReadReceipt || '');
320
321
			this.computeSenderEmail();
322
323
			result = true;
324
		}
325
326
		return result;
327
	}
328
329
	/**
330
	 * @param {(AjaxJsonAttachment|null)} oJsonAttachments
0 ignored issues
show
Documentation introduced by
The parameter oJsonAttachments does not exist. Did you maybe forget to remove this comment?
Loading history...
331
	 * @returns {Array}
332
	 */
333
	initAttachmentsFromJson(json) {
334
		let
335
			index = 0,
336
			len = 0,
337
			attachment = null;
0 ignored issues
show
Unused Code introduced by
The assignment to attachment seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
338
		const result = [];
339
340
		if (json && 'Collection/AttachmentCollection' === json['@Object'] && isNonEmptyArray(json['@Collection']))
341
		{
342
			for (index = 0, len = json['@Collection'].length; index < len; index++)
343
			{
344
				attachment = AttachmentModel.newInstanceFromJson(json['@Collection'][index]);
345
				if (attachment)
346
				{
347
					if ('' !== attachment.cidWithOutTags && 0 < this.foundedCIDs.length &&
348
						0 <= inArray(attachment.cidWithOutTags, this.foundedCIDs))
349
					{
350
						attachment.isLinked = true;
351
					}
352
353
					result.push(attachment);
354
				}
355
			}
356
		}
357
358
		return result;
359
	}
360
361
	/**
362
	 * @returns {boolean}
363
	 */
364
	hasUnsubsribeLinks() {
365
		return this.unsubsribeLinks && 0 < this.unsubsribeLinks.length;
366
	}
367
368
	/**
369
	 * @returns {string}
370
	 */
371
	getFirstUnsubsribeLink() {
372
		return this.unsubsribeLinks && 0 < this.unsubsribeLinks.length ? (this.unsubsribeLinks[0] || '') : '';
373
	}
374
375
	/**
376
	 * @param {AjaxJsonMessage} json
377
	 * @returns {boolean}
378
	 */
379
	initFlagsByJson(json) {
380
		let result = false;
381
		if (json && 'Object/Message' === json['@Object'])
382
		{
383
			this.unseen(!json.IsSeen);
384
			this.flagged(!!json.IsFlagged);
385
			this.answered(!!json.IsAnswered);
386
			this.forwarded(!!json.IsForwarded);
387
			this.isReadReceipt(!!json.IsReadReceipt);
388
			this.deletedMark(!!json.IsDeleted);
389
390
			result = true;
391
		}
392
393
		return result;
394
	}
395
396
	/**
397
	 * @param {boolean} friendlyView
398
	 * @param {boolean=} wrapWithLink = false
399
	 * @returns {string}
400
	 */
401
	fromToLine(friendlyView, wrapWithLink = false) {
402
		return emailArrayToString(this.from, friendlyView, wrapWithLink);
403
	}
404
405
	/**
406
	 * @returns {string}
407
	 */
408
	fromDkimData() {
409
		let result = ['none', ''];
410
		if (isNonEmptyArray(this.from) && 1 === this.from.length && this.from[0] && this.from[0].dkimStatus)
411
		{
412
			result = [this.from[0].dkimStatus, this.from[0].dkimValue || ''];
413
		}
414
415
		return result;
416
	}
417
418
	/**
419
	 * @param {boolean} friendlyView
420
	 * @param {boolean=} wrapWithLink = false
421
	 * @returns {string}
422
	 */
423
	toToLine(friendlyView, wrapWithLink = false) {
424
		return emailArrayToString(this.to, friendlyView, wrapWithLink);
425
	}
426
427
	/**
428
	 * @param {boolean} friendlyView
429
	 * @param {boolean=} wrapWithLink = false
430
	 * @returns {string}
431
	 */
432
	ccToLine(friendlyView, wrapWithLink = false) {
433
		return emailArrayToString(this.cc, friendlyView, wrapWithLink);
434
	}
435
436
	/**
437
	 * @param {boolean} friendlyView
438
	 * @param {boolean=} wrapWithLink = false
439
	 * @returns {string}
440
	 */
441
	bccToLine(friendlyView, wrapWithLink = false) {
442
		return emailArrayToString(this.bcc, friendlyView, wrapWithLink);
443
	}
444
445
	/**
446
	 * @param {boolean} friendlyView
447
	 * @param {boolean=} wrapWithLink = false
448
	 * @returns {string}
449
	 */
450
	replyToToLine(friendlyView, wrapWithLink = false) {
451
		return emailArrayToString(this.replyTo, friendlyView, wrapWithLink);
452
	}
453
454
	/**
455
	 * @return string
456
	 */
457
	lineAsCss() {
458
		const result = [];
459
		if (this.deleted())
460
		{
461
			result.push('deleted');
462
		}
463
		if (this.deletedMark())
464
		{
465
			result.push('deleted-mark');
466
		}
467
		if (this.selected())
468
		{
469
			result.push('selected');
470
		}
471
		if (this.checked())
472
		{
473
			result.push('checked');
474
		}
475
		if (this.flagged())
476
		{
477
			result.push('flagged');
478
		}
479
		if (this.unseen())
480
		{
481
			result.push('unseen');
482
		}
483
		if (this.answered())
484
		{
485
			result.push('answered');
486
		}
487
		if (this.forwarded())
488
		{
489
			result.push('forwarded');
490
		}
491
		if (this.focused())
492
		{
493
			result.push('focused');
494
		}
495
		if (this.isImportant())
496
		{
497
			result.push('important');
498
		}
499
		if (this.hasAttachments())
500
		{
501
			result.push('withAttachments');
502
		}
503
		if (this.newForAnimation())
504
		{
505
			result.push('new');
506
		}
507
		if ('' === this.subject())
508
		{
509
			result.push('emptySubject');
510
		}
511
//		if (1 < this.threadsLen())
512
//		{
513
//			result.push('hasChildrenMessage');
514
//		}
515
		if (this.hasUnseenSubMessage())
516
		{
517
			result.push('hasUnseenSubMessage');
518
		}
519
		if (this.hasFlaggedSubMessage())
520
		{
521
			result.push('hasFlaggedSubMessage');
522
		}
523
524
		return result.join(' ');
525
	}
526
527
	/**
528
	 * @returns {boolean}
529
	 */
530
	hasVisibleAttachments() {
531
		return !!_.find(this.attachments(), (item) => !item.isLinked);
532
	}
533
534
	/**
535
	 * @param {string} cid
536
	 * @returns {*}
537
	 */
538
	findAttachmentByCid(cid) {
539
		let result = null;
540
		const attachments = this.attachments();
541
542
		if (isNonEmptyArray(attachments))
543
		{
544
			cid = cid.replace(/^<+/, '').replace(/>+$/, '');
545
			result = _.find(attachments, (item) => cid === item.cidWithOutTags);
546
		}
547
548
		return result || null;
549
	}
550
551
	/**
552
	 * @param {string} contentLocation
553
	 * @returns {*}
554
	 */
555
	findAttachmentByContentLocation(contentLocation) {
556
		let result = null;
557
		const attachments = this.attachments();
558
559
		if (isNonEmptyArray(attachments))
560
		{
561
			result = _.find(attachments, (item) => contentLocation === item.contentLocation);
562
		}
563
564
		return result || null;
565
	}
566
567
	/**
568
	 * @returns {string}
569
	 */
570
	messageId() {
571
		return this.sMessageId;
572
	}
573
574
	/**
575
	 * @returns {string}
576
	 */
577
	inReplyTo() {
578
		return this.sInReplyTo;
579
	}
580
581
	/**
582
	 * @returns {string}
583
	 */
584
	references() {
585
		return this.sReferences;
586
	}
587
588
	/**
589
	 * @returns {string}
590
	 */
591
	fromAsSingleEmail() {
592
		return isArray(this.from) && this.from[0] ? this.from[0].email : '';
593
	}
594
595
	/**
596
	 * @returns {string}
597
	 */
598
	viewLink() {
599
		return messageViewLink(this.requestHash);
600
	}
601
602
	/**
603
	 * @returns {string}
604
	 */
605
	downloadLink() {
606
		return messageDownloadLink(this.requestHash);
607
	}
608
609
	/**
610
	 * @param {Object} excludeEmails
611
	 * @param {boolean=} last = false
612
	 * @returns {Array}
613
	 */
614
	replyEmails(excludeEmails, last = false) {
615
		const
616
			result = [],
617
			unic = isUnd(excludeEmails) ? {} : excludeEmails;
618
619
		replyHelper(this.replyTo, unic, result);
620
		if (0 === result.length)
621
		{
622
			replyHelper(this.from, unic, result);
623
		}
624
625
		if (0 === result.length && !last)
626
		{
627
			return this.replyEmails({}, true);
628
		}
629
630
		return result;
631
	}
632
633
	/**
634
	 * @param {Object} excludeEmails
635
	 * @param {boolean=} last = false
636
	 * @returns {Array.<Array>}
637
	 */
638
	replyAllEmails(excludeEmails, last = false) {
639
		let data = [];
0 ignored issues
show
Unused Code introduced by
The assignment to variable data seems to be never used. Consider removing it.
Loading history...
640
		const
641
			toResult = [],
642
			ccResult = [],
643
			unic = isUnd(excludeEmails) ? {} : excludeEmails;
644
645
		replyHelper(this.replyTo, unic, toResult);
646
		if (0 === toResult.length)
647
		{
648
			replyHelper(this.from, unic, toResult);
649
		}
650
651
		replyHelper(this.to, unic, toResult);
652
		replyHelper(this.cc, unic, ccResult);
653
654
		if (0 === toResult.length && !last)
655
		{
656
			data = this.replyAllEmails({}, true);
657
			return [data[0], ccResult];
658
		}
659
660
		return [toResult, ccResult];
661
	}
662
663
	/**
664
	 * @returns {string}
665
	 */
666
	textBodyToString() {
667
		return this.body ? this.body.html() : '';
668
	}
669
670
	/**
671
	 * @returns {string}
672
	 */
673
	attachmentsToStringLine() {
674
		const attachLines = _.map(this.attachments(), (item) => item.fileName + ' (' + item.friendlySize + ')');
675
		return attachLines && 0 < attachLines.length ? attachLines.join(', ') : '';
676
	}
677
678
	/**
679
	 * @param {boolean=} print = false
680
	 */
681
	viewPopupMessage(print = false) {
682
		this.showLazyExternalImagesInBody();
683
		previewMessage(this.subject(), this.body, this.isHtml(), print);
684
	}
685
686
	printMessage() {
687
		this.viewPopupMessage(true);
688
	}
689
690
	/**
691
	 * @returns {string}
692
	 */
693
	generateUid() {
694
		return this.folderFullNameRaw + '/' + this.uid;
695
	}
696
697
	/**
698
	 * @param {MessageModel} message
699
	 * @returns {MessageModel}
700
	 */
701
	populateByMessageListItem(message) {
702
		if (message)
703
		{
704
			this.folderFullNameRaw = message.folderFullNameRaw;
705
			this.uid = message.uid;
706
			this.hash = message.hash;
707
			this.requestHash = message.requestHash;
708
			this.subject(message.subject());
709
		}
710
711
		this.subjectPrefix(this.subjectPrefix());
712
		this.subjectSuffix(this.subjectSuffix());
713
714
		if (message)
715
		{
716
			this.size(message.size());
717
			this.dateTimeStampInUTC(message.dateTimeStampInUTC());
718
			this.priority(message.priority());
719
720
			this.proxy = message.proxy;
721
722
			this.fromEmailString(message.fromEmailString());
723
			this.fromClearEmailString(message.fromClearEmailString());
724
			this.toEmailsString(message.toEmailsString());
725
			this.toClearEmailsString(message.toClearEmailsString());
726
727
			this.emails = message.emails;
728
729
			this.from = message.from;
730
			this.to = message.to;
731
			this.cc = message.cc;
732
			this.bcc = message.bcc;
733
			this.replyTo = message.replyTo;
734
			this.deliveredTo = message.deliveredTo;
735
			this.unsubsribeLinks = message.unsubsribeLinks;
736
737
			this.unseen(message.unseen());
738
			this.flagged(message.flagged());
739
			this.answered(message.answered());
740
			this.forwarded(message.forwarded());
741
			this.isReadReceipt(message.isReadReceipt());
742
			this.deletedMark(message.deletedMark());
743
744
			this.priority(message.priority());
745
746
			this.selected(message.selected());
747
			this.checked(message.checked());
748
			this.hasAttachments(message.hasAttachments());
749
			this.attachmentsSpecData(message.attachmentsSpecData());
750
		}
751
752
		this.body = null;
753
754
		this.aDraftInfo = [];
755
		this.sMessageId = '';
756
		this.sInReplyTo = '';
757
		this.sReferences = '';
758
759
		if (message)
760
		{
761
			this.threads(message.threads());
762
		}
763
764
		this.computeSenderEmail();
765
766
		return this;
767
	}
768
769
	showLazyExternalImagesInBody() {
770
		if (this.body)
771
		{
772
			$('.lazy.lazy-inited[data-original]', this.body).each(function() {
773
				$(this).attr('src', $(this).attr('data-original')).removeAttr('data-original');
774
			});
775
		}
776
	}
777
778
	showExternalImages(lazy = false) {
779
		if (this.body && this.body.data('rl-has-images'))
780
		{
781
			this.hasImages(false);
782
			this.body.data('rl-has-images', false);
783
784
			var sAttr = this.proxy ? 'data-x-additional-src' : 'data-x-src';
785
			$('[' + sAttr + ']', this.body).each(function() {
786
				if (lazy && $(this).is('img'))
787
				{
788
					$(this)
789
						.addClass('lazy')
790
						.attr('data-original', $(this).attr(sAttr))
791
						.removeAttr(sAttr);
792
				}
793
				else
794
				{
795
					$(this).attr('src', $(this).attr(sAttr)).removeAttr(sAttr);
796
				}
797
			});
798
799
			sAttr = this.proxy ? 'data-x-additional-style-url' : 'data-x-style-url';
800
			$('[' + sAttr + ']', this.body).each(function() {
801
				var sStyle = trim($(this).attr('style'));
802
				sStyle = '' === sStyle ? '' : (';' === sStyle.substr(-1) ? sStyle + ' ' : sStyle + '; ');
803
				$(this).attr('style', sStyle + $(this).attr(sAttr)).removeAttr(sAttr);
804
			});
805
806
			if (lazy)
807
			{
808
				$('img.lazy', this.body).addClass('lazy-inited').lazyload({
809
					'threshold': 400,
810
					'effect': 'fadeIn',
811
					'skip_invisible': false,
812
					'container': $('.RL-MailMessageView .messageView .messageItem .content')[0]
813
				});
814
815
				$win.resize();
816
			}
817
818
			windowResize(500);
819
		}
820
	}
821
822
	showInternalImages(lazy = false) {
823
		if (this.body && !this.body.data('rl-init-internal-images'))
824
		{
825
			this.body.data('rl-init-internal-images', true);
826
827
			var self = this;
828
829
			$('[data-x-src-cid]', this.body).each(function() {
830
				const attachment = self.findAttachmentByCid($(this).attr('data-x-src-cid'));
831
				if (attachment && attachment.download)
832
				{
833
					if (lazy && $(this).is('img'))
834
					{
835
						$(this)
836
							.addClass('lazy')
837
							.attr('data-original', attachment.linkPreview());
838
					}
839
					else
840
					{
841
						$(this).attr('src', attachment.linkPreview());
842
					}
843
				}
844
			});
845
846
			$('[data-x-src-location]', this.body).each(function() {
847
				let attachment = self.findAttachmentByContentLocation($(this).attr('data-x-src-location'));
848
				if (!attachment)
849
				{
850
					attachment = self.findAttachmentByCid($(this).attr('data-x-src-location'));
851
				}
852
853
				if (attachment && attachment.download)
854
				{
855
					if (lazy && $(this).is('img'))
856
					{
857
						$(this)
858
							.addClass('lazy')
859
							.attr('data-original', attachment.linkPreview());
860
					}
861
					else
862
					{
863
						$(this).attr('src', attachment.linkPreview());
864
					}
865
				}
866
			});
867
868
			$('[data-x-style-cid]', this.body).each(function() {
869
				let
870
					style = '',
871
					name = '';
872
				const attachment = self.findAttachmentByCid($(this).attr('data-x-style-cid'));
873
874
				if (attachment && attachment.linkPreview)
875
				{
876
					name = $(this).attr('data-x-style-cid-name');
877
					if ('' !== name)
878
					{
879
						style = trim($(this).attr('style'));
880
						style = '' === style ? '' : (';' === style.substr(-1) ? style + ' ' : style + '; ');
881
						$(this).attr('style', style + name + ': url(\'' + attachment.linkPreview() + '\')');
882
					}
883
				}
884
			});
885
886
			if (lazy)
887
			{
888
				(function($oImg, oContainer) {
889
					_.delay(() => {
890
						$oImg.addClass('lazy-inited').lazyload({
891
							'threshold': 400,
892
							'effect': 'fadeIn',
893
							'skip_invisible': false,
894
							'container': oContainer
895
						});
896
					}, 300);
897
				}($('img.lazy', self.body), $('.RL-MailMessageView .messageView .messageItem .content')[0]));
898
			}
899
900
			windowResize(500);
901
		}
902
	}
903
904
	storeDataInDom() {
905
		if (this.body)
906
		{
907
			this.body.data('rl-is-html', !!this.isHtml());
908
			this.body.data('rl-has-images', !!this.hasImages());
909
		}
910
	}
911
912
	fetchDataFromDom() {
913
		if (this.body)
914
		{
915
			this.isHtml(!!this.body.data('rl-is-html'));
916
			this.hasImages(!!this.body.data('rl-has-images'));
917
		}
918
	}
919
920
	replacePlaneTextBody(plain) {
921
		if (this.body)
922
		{
923
			this.body.html(plain).addClass('b-text-part plain');
924
		}
925
	}
926
927
	/**
928
	 * @returns {string}
929
	 */
930
	flagHash() {
931
		return [this.deleted(), this.deletedMark(), this.unseen(), this.flagged(), this.answered(), this.forwarded(), this.isReadReceipt()].join(',');
932
	}
933
}
934
935
export {MessageModel, MessageModel as default};
936